{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting tensorflow_probability\n",
      "  Downloading tensorflow_probability-0.11.1-py2.py3-none-any.whl (4.3 MB)\n",
      "\u001b[K     |████████████████████████████████| 4.3 MB 2.0 MB/s eta 0:00:01\n",
      "\u001b[?25hRequirement already satisfied: tensorboard in /Users/ben/.local/lib/python3.6/site-packages (1.15.0)\n",
      "Requirement already satisfied: cloudpickle>=1.3 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow_probability) (1.3.0)\n",
      "Requirement already satisfied: six>=1.10.0 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow_probability) (1.15.0)\n",
      "Requirement already satisfied: decorator in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow_probability) (4.4.2)\n",
      "Collecting gast>=0.3.2\n",
      "  Downloading gast-0.4.0-py3-none-any.whl (9.8 kB)\n",
      "Collecting dm-tree\n",
      "  Downloading dm_tree-0.1.5-cp36-cp36m-macosx_10_9_x86_64.whl (94 kB)\n",
      "\u001b[K     |████████████████████████████████| 94 kB 868 kB/s  eta 0:00:01\n",
      "\u001b[?25hRequirement already satisfied: numpy>=1.13.3 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow_probability) (1.19.1)\n",
      "Requirement already satisfied: markdown>=2.6.8 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard) (2.6.11)\n",
      "Requirement already satisfied: protobuf>=3.6.0 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard) (3.12.2)\n",
      "Requirement already satisfied: werkzeug>=0.11.15 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard) (0.14.1)\n",
      "Requirement already satisfied: grpcio>=1.6.3 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard) (1.16.1)\n",
      "Requirement already satisfied: absl-py>=0.4 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard) (0.8.1)\n",
      "Requirement already satisfied: wheel>=0.26; python_version >= \"3\" in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard) (0.35.1)\n",
      "Requirement already satisfied: setuptools>=41.0.0 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard) (49.6.0.post20200814)\n",
      "Installing collected packages: gast, dm-tree, tensorflow-probability\n",
      "  Attempting uninstall: gast\n",
      "    Found existing installation: gast 0.2.2\n",
      "    Uninstalling gast-0.2.2:\n",
      "      Successfully uninstalled gast-0.2.2\n",
      "\u001b[31mERROR: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts.\n",
      "\n",
      "We recommend you use --use-feature=2020-resolver to test your packages with the new resolver before it becomes the default.\n",
      "\n",
      "tensorflow 1.15.3 requires gast==0.2.2, but you'll have gast 0.4.0 which is incompatible.\u001b[0m\n",
      "Successfully installed dm-tree-0.1.5 gast-0.4.0 tensorflow-probability-0.11.1\n"
     ]
    }
   ],
   "source": [
    "!pip install tensorflow_probability tensorboard"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting tensorflow>=2.3\n",
      "  Downloading tensorflow-2.3.1-cp36-cp36m-macosx_10_9_x86_64.whl (165.1 MB)\n",
      "\u001b[K     |████████████████████████████████| 165.1 MB 49 kB/s  eta 0:00:012   |███████▊                        | 40.1 MB 4.2 MB/s eta 0:00:31     |████████▎                       | 42.7 MB 5.7 MB/s eta 0:00:22     |███████████                     | 56.5 MB 2.6 MB/s eta 0:00:42     |███████████████▍                | 79.4 MB 3.2 MB/s eta 0:00:27     |████████████████▌               | 85.1 MB 4.7 MB/s eta 0:00:17     |██████████████████▏             | 93.6 MB 1.9 MB/s eta 0:00:37     |████████████████████            | 103.6 MB 4.2 MB/s eta 0:00:15     |█████████████████████████▉      | 133.3 MB 5.9 MB/s eta 0:00:06\n",
      "\u001b[?25hCollecting numpy<1.19.0,>=1.16.0\n",
      "  Downloading numpy-1.18.5-cp36-cp36m-macosx_10_9_x86_64.whl (15.1 MB)\n",
      "\u001b[K     |████████████████████████████████| 15.1 MB 8.4 MB/s eta 0:00:01    |██████████████                  | 6.6 MB 4.0 MB/s eta 0:00:03     |███████████████████████████▏    | 12.9 MB 8.4 MB/s eta 0:00:01\n",
      "\u001b[?25hRequirement already satisfied: keras-preprocessing<1.2,>=1.1.1 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow>=2.3) (1.1.2)\n",
      "Requirement already satisfied: termcolor>=1.1.0 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow>=2.3) (1.1.0)\n",
      "Requirement already satisfied: grpcio>=1.8.6 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow>=2.3) (1.16.1)\n",
      "Requirement already satisfied: absl-py>=0.7.0 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow>=2.3) (0.8.1)\n",
      "Requirement already satisfied: google-pasta>=0.1.8 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow>=2.3) (0.1.8)\n",
      "Collecting tensorflow-estimator<2.4.0,>=2.3.0\n",
      "  Downloading tensorflow_estimator-2.3.0-py2.py3-none-any.whl (459 kB)\n",
      "\u001b[K     |████████████████████████████████| 459 kB 11.6 MB/s eta 0:00:01\n",
      "\u001b[?25hCollecting tensorboard<3,>=2.3.0\n",
      "  Downloading tensorboard-2.3.0-py3-none-any.whl (6.8 MB)\n",
      "\u001b[K     |████████████████████████████████| 6.8 MB 7.9 MB/s eta 0:00:011\n",
      "\u001b[?25hRequirement already satisfied: protobuf>=3.9.2 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow>=2.3) (3.12.2)\n",
      "Requirement already satisfied: wrapt>=1.11.1 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow>=2.3) (1.11.2)\n",
      "Requirement already satisfied: opt-einsum>=2.3.2 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow>=2.3) (3.2.1)\n",
      "Requirement already satisfied: wheel>=0.26 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow>=2.3) (0.35.1)\n",
      "Requirement already satisfied: h5py<2.11.0,>=2.10.0 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow>=2.3) (2.10.0)\n",
      "Requirement already satisfied: astunparse==1.6.3 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow>=2.3) (1.6.3)\n",
      "Requirement already satisfied: six>=1.12.0 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorflow>=2.3) (1.15.0)\n",
      "Collecting gast==0.3.3\n",
      "  Using cached gast-0.3.3-py2.py3-none-any.whl (9.7 kB)\n",
      "Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard<3,>=2.3.0->tensorflow>=2.3) (1.6.0.post3)\n",
      "Requirement already satisfied: markdown>=2.6.8 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard<3,>=2.3.0->tensorflow>=2.3) (2.6.11)\n",
      "Requirement already satisfied: setuptools>=41.0.0 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard<3,>=2.3.0->tensorflow>=2.3) (49.6.0.post20200814)\n",
      "Requirement already satisfied: requests<3,>=2.21.0 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard<3,>=2.3.0->tensorflow>=2.3) (2.24.0)\n",
      "Requirement already satisfied: google-auth<2,>=1.6.3 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard<3,>=2.3.0->tensorflow>=2.3) (1.17.2)\n",
      "Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard<3,>=2.3.0->tensorflow>=2.3) (0.4.1)\n",
      "Requirement already satisfied: werkzeug>=0.11.15 in /Users/ben/anaconda3/lib/python3.6/site-packages (from tensorboard<3,>=2.3.0->tensorflow>=2.3) (0.14.1)\n",
      "Requirement already satisfied: idna<3,>=2.5 in /Users/ben/anaconda3/lib/python3.6/site-packages (from requests<3,>=2.21.0->tensorboard<3,>=2.3.0->tensorflow>=2.3) (2.10)\n",
      "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /Users/ben/anaconda3/lib/python3.6/site-packages (from requests<3,>=2.21.0->tensorboard<3,>=2.3.0->tensorflow>=2.3) (1.25.10)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /Users/ben/anaconda3/lib/python3.6/site-packages (from requests<3,>=2.21.0->tensorboard<3,>=2.3.0->tensorflow>=2.3) (2020.6.20)\n",
      "Requirement already satisfied: chardet<4,>=3.0.2 in /Users/ben/anaconda3/lib/python3.6/site-packages (from requests<3,>=2.21.0->tensorboard<3,>=2.3.0->tensorflow>=2.3) (3.0.4)\n",
      "Requirement already satisfied: pyasn1-modules>=0.2.1 in /Users/ben/anaconda3/lib/python3.6/site-packages (from google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow>=2.3) (0.2.1)\n",
      "Requirement already satisfied: rsa<5,>=3.1.4; python_version >= \"3\" in /Users/ben/anaconda3/lib/python3.6/site-packages (from google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow>=2.3) (4.6)\n",
      "Requirement already satisfied: cachetools<5.0,>=2.0.0 in /Users/ben/anaconda3/lib/python3.6/site-packages (from google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow>=2.3) (4.1.0)\n",
      "Requirement already satisfied: requests-oauthlib>=0.7.0 in /Users/ben/anaconda3/lib/python3.6/site-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard<3,>=2.3.0->tensorflow>=2.3) (1.0.0)\n",
      "Requirement already satisfied: pyasn1<0.5.0,>=0.4.1 in /Users/ben/anaconda3/lib/python3.6/site-packages (from pyasn1-modules>=0.2.1->google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow>=2.3) (0.4.4)\n",
      "Requirement already satisfied: oauthlib>=0.6.2 in /Users/ben/anaconda3/lib/python3.6/site-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard<3,>=2.3.0->tensorflow>=2.3) (2.1.0)\n",
      "Installing collected packages: numpy, tensorflow-estimator, tensorboard, gast, tensorflow\n",
      "  Attempting uninstall: numpy\n",
      "    Found existing installation: numpy 1.19.1\n",
      "    Uninstalling numpy-1.19.1:\n",
      "      Successfully uninstalled numpy-1.19.1\n",
      "  Attempting uninstall: tensorflow-estimator\n",
      "    Found existing installation: tensorflow-estimator 1.15.1\n",
      "    Uninstalling tensorflow-estimator-1.15.1:\n",
      "      Successfully uninstalled tensorflow-estimator-1.15.1\n",
      "  Attempting uninstall: tensorboard\n",
      "    Found existing installation: tensorboard 1.15.0\n",
      "    Uninstalling tensorboard-1.15.0:\n",
      "      Successfully uninstalled tensorboard-1.15.0\n",
      "  Attempting uninstall: gast\n",
      "    Found existing installation: gast 0.4.0\n",
      "    Uninstalling gast-0.4.0:\n",
      "      Successfully uninstalled gast-0.4.0\n",
      "  Attempting uninstall: tensorflow\n",
      "    Found existing installation: tensorflow 1.15.3\n",
      "    Uninstalling tensorflow-1.15.3:\n",
      "      Successfully uninstalled tensorflow-1.15.3\n",
      "\u001b[31mERROR: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts.\n",
      "\n",
      "We recommend you use --use-feature=2020-resolver to test your packages with the new resolver before it becomes the default.\n",
      "\n",
      "tensorboard 2.3.0 requires grpcio>=1.24.3, but you'll have grpcio 1.16.1 which is incompatible.\n",
      "torchvision 0.6.1 requires torch==1.5.1, but you'll have torch 1.6.0 which is incompatible.\u001b[0m\n",
      "Successfully installed gast-0.3.3 numpy-1.18.5 tensorboard-2.3.0 tensorflow-2.3.1 tensorflow-estimator-2.3.0\n"
     ]
    }
   ],
   "source": [
    "!pip install 'tensorflow>=2.3'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.datasets import fetch_openml\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "X, y = fetch_openml(data_id=1565, return_X_y=True, as_frame=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>V1</th>\n",
       "      <th>V2</th>\n",
       "      <th>V3</th>\n",
       "      <th>V4</th>\n",
       "      <th>V5</th>\n",
       "      <th>V6</th>\n",
       "      <th>V7</th>\n",
       "      <th>V8</th>\n",
       "      <th>V9</th>\n",
       "      <th>V10</th>\n",
       "      <th>V11</th>\n",
       "      <th>V12</th>\n",
       "      <th>V13</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>40.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>140.0</td>\n",
       "      <td>289.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>172.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-9.0</td>\n",
       "      <td>-9.0</td>\n",
       "      <td>-9.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>49.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>160.0</td>\n",
       "      <td>180.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>156.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>-9.0</td>\n",
       "      <td>-9.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>37.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>130.0</td>\n",
       "      <td>283.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>98.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-9.0</td>\n",
       "      <td>-9.0</td>\n",
       "      <td>-9.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>48.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>138.0</td>\n",
       "      <td>214.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>108.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.5</td>\n",
       "      <td>2.0</td>\n",
       "      <td>-9.0</td>\n",
       "      <td>-9.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>54.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>150.0</td>\n",
       "      <td>-9.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>122.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-9.0</td>\n",
       "      <td>-9.0</td>\n",
       "      <td>-9.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     V1   V2   V3     V4     V5   V6   V7     V8   V9  V10  V11  V12  V13\n",
       "0  40.0  1.0  2.0  140.0  289.0  0.0  0.0  172.0  0.0  0.0 -9.0 -9.0 -9.0\n",
       "1  49.0  0.0  3.0  160.0  180.0  0.0  0.0  156.0  0.0  1.0  2.0 -9.0 -9.0\n",
       "2  37.0  1.0  2.0  130.0  283.0  0.0  1.0   98.0  0.0  0.0 -9.0 -9.0 -9.0\n",
       "3  48.0  0.0  4.0  138.0  214.0  0.0  0.0  108.0  1.0  1.5  2.0 -9.0 -9.0\n",
       "4  54.0  1.0  3.0  150.0   -9.0  0.0  0.0  122.0  0.0  0.0 -9.0 -9.0 -9.0"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.astype(int).min()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7fda40ce2be0>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "y.hist(bins=5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "target = (y.astype(int) > 1).astype(float)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 216x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "\n",
    "target.hist(figsize=(3, 5), rwidth=5)\n",
    "plt.xticks([0.05, 0.95], ['healthy', 'unhealthy'])\n",
    "plt.grid(b=None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "scaler = StandardScaler()\n",
    "X_t = scaler.fit_transform(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.00359234,  0.61666984, -1.02025916, ..., -0.73929521,\n",
       "        -0.11089228, -0.32235972],\n",
       "       [ 0.15047343, -1.62161328,  0.01765154, ...,  1.37092607,\n",
       "        -0.11089228, -0.32235972],\n",
       "       [-1.38828093,  0.61666984, -1.02025916, ..., -0.73929521,\n",
       "        -0.11089228, -0.32235972],\n",
       "       ...,\n",
       "       [ 0.0222439 ,  0.61666984,  0.01765154, ..., -0.73929521,\n",
       "        -0.11089228,  3.14497288],\n",
       "       [-0.10598563, -1.62161328, -1.02025916, ...,  1.17908777,\n",
       "        -0.11089228, -0.32235972],\n",
       "       [ 0.66339155,  0.61666984,  1.05556224, ..., -0.73929521,\n",
       "        -0.11089228, -0.32235972]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "Xt_train, Xt_test, y_train, y_test = train_test_split(\n",
    "    X_t, target, test_size=0.33, random_state=42\n",
    ")  # for neural networks\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    X, target, test_size=0.33, random_state=42\n",
    ")  # for decision tree approaches"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.isnull().sum(axis=0).any()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "import tensorflow_probability as tfp\n",
    "tfd = tfp.distributions\n",
    "from tensorflow import keras\n",
    "\n",
    "negloglik = lambda y, p_y: -p_y.log_prob(y)\n",
    "\n",
    "model = keras.Sequential([\n",
    "  keras.layers.Dense(12, activation='relu', name='hidden'),\n",
    "  keras.layers.Dense(1, name='output'),\n",
    "  tfp.layers.DistributionLambda(\n",
    "      lambda t: tfd.Bernoulli(logits=t)\n",
    "  ),\n",
    "])\n",
    "\n",
    "model.compile(optimizer=tf.optimizers.Adagrad(learning_rate=0.05), loss=negloglik)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The tensorboard extension is already loaded. To reload it, use:\n",
      "  %reload_ext tensorboard\n"
     ]
    }
   ],
   "source": [
    "%load_ext tensorboard"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /Users/ben/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/summary_ops_v2.py:1277: stop (from tensorflow.python.eager.profiler) is deprecated and will be removed after 2020-07-01.\n",
      "Instructions for updating:\n",
      "use `tf.profiler.experimental.stop` instead.\n",
      "WARNING:tensorflow:Callbacks method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0012s vs `on_train_batch_end` time: 0.0222s). Check your callbacks.\n"
     ]
    }
   ],
   "source": [
    "callbacks = [\n",
    "    keras.callbacks.EarlyStopping(patience=10, monitor='loss'),\n",
    "    keras.callbacks.TensorBoard(log_dir='./logs'),\n",
    "]\n",
    "history = model.fit(\n",
    "    Xt_train,\n",
    "    y_train.values,\n",
    "    epochs=10000,\n",
    "    verbose=False,\n",
    "    callbacks=callbacks\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2975\n"
     ]
    }
   ],
   "source": [
    "print(len(history.epoch))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "hidden (Dense)               (None, 12)                168       \n",
      "_________________________________________________________________\n",
      "output (Dense)               (None, 1)                 13        \n",
      "_________________________________________________________________\n",
      "distribution_lambda (Distrib ((None, 1), (None, 1))    0         \n",
      "=================================================================\n",
      "Total params: 181\n",
      "Trainable params: 181\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = model(Xt_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "def to_one_hot(a):\n",
    "    \"\"\"convert from integer encoding to one-hot\"\"\"\n",
    "    b = np.zeros((a.size, 2))\n",
    "    b[np.arange(a.size), np.rint(a).astype(int)] = 1\n",
    "    return b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.rcParams[\"font.family\"] = \"Times New Roman\"\n",
    "plt.rcParams[\"font.size\"] = \"15\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from scipy.stats import norm\n",
    "import numpy as np\n",
    "\n",
    "\n",
    "a, b = y_pred.mean().numpy()[10], y_pred.variance().numpy()[10]\n",
    "fig, ax = plt.subplots(1, 1)\n",
    "x = np.linspace(\n",
    "    norm.ppf(0.001, a, b),\n",
    "    norm.ppf(0.999, a, b),\n",
    "    100\n",
    ")\n",
    "pdf = norm.pdf(x, a, b)\n",
    "ax.plot(\n",
    "    x, \n",
    "    pdf / np.sum(pdf), \n",
    "    'r-', lw=5, alpha=0.6, \n",
    "    label='norm pdf'\n",
    ")\n",
    "plt.ylabel('probability density')\n",
    "plt.xlabel('predictions');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "def to_classprobs(y_pred):\n",
    "    class_probs = np.zeros(shape=(y_pred.mean().numpy().shape[0], 2))\n",
    "    for i, (a, b) in enumerate(zip(y_pred.mean().numpy(), y_pred.variance().numpy())):\n",
    "        conf = norm.cdf(0.5, a, b)\n",
    "        class_probs[i, 0] = conf\n",
    "        class_probs[i, 1] = 1 - conf\n",
    "    return class_probs\n",
    "\n",
    "class_probs = to_classprobs(y_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sklearn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'auc score: 0.810'"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'auc score: {:.3f}'.format(sklearn.metrics.roc_auc_score(to_one_hot(y_test), class_probs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ModelWrapper(sklearn.base.ClassifierMixin):\n",
    "    _estimator_type = 'classifier'\n",
    "    classes_ = [0, 1]\n",
    "    def predict_proba(self, X):\n",
    "        pred = model(X)\n",
    "        return to_classprobs(pred)\n",
    "    \n",
    "model_wrapper = ModelWrapper()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, '2-class Precision-Recall curve: AP=0.77')"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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RCSWEoSIiMRSghARkVhKECIiEksJQkREYilBiIhILCUIERGJpQQhIiKxlCBERCSWEoSIiMRSghARkVhKECIiEksJQkREYilBiIhILCUIERGJpQQhIiKxlCBERCSWEoSIiMRSghARkVhKECIiEksJQkREYilBiIhILCUIERGJpQQhIiKxlCBERCSWEoSIiMRSghARkVhKECIiEksJQkREYilBiIhILCUIERGJpQQhIiKxlCBERCSWEoSIiMRSghARkVhKECIiEksJQkREYilBiIhILCUIERGJpQQhIiKxlCBERCSWEoSIiMRSghARkVhVyzuATFqzZg1Lly5l06ZN5R2KyHapWrVqNG7cmNq1a5d3KFIKMpogzKwqMBLYAuwMjHL32UVMMwTo7u7dSrLsNWvW8OOPP9K8eXNq1qyJmZVkdiKSxN3Jzs5m0aJFAEoS24FMdzHdASx396HAEOApM6tXUGUz6wgMKo0FL126lObNm1OrVi0lB5EyYGbUqlWL5s2bs3Tp0vIOR0pBxhKEmTUi7OwfB3D3lcDnwIAC6tcG+gKTSmP5mzZtombNmqUxKxEpRM2aNdWNu53IZAviyOjvdwll84CjCqh/LXAd4KUVgFoOImVP37PtRyYTxC7ASndP3OGvAVokVzSzc4B/u/uyomZqZv3NbJaZzVq2rMjqIiKSokwmCAeyY5a/ObHAzPYGGrj7GynN1H28u3dw9w6NGjUqnUhFRCSjCWIhkHxAul5UnmgIcI2ZrTaz1cBQ4LBoeNcMxFkpuTvPPPMMBx98MK+//nqhdT/77DP69+/PCSeckJngtiGff/45lbGlumzZMr766qvyDkMyLJMJ4lWgupk1TyhrDbyUVO8qYH/ggOh1HzAr+n9xBuLcJs2YMYPOnTtjZrzxRnzj6pdffqFhw4bssssuPPvss+Tk5KS1jLp16/LBBx8UWa9Zs2Zs3LiRX375BYA333yTvfbaCzNj4sSJAEycOJGaNWtSt25dpk2bljft1KlTadq0Kddffz3Z2ckNym3bs88+y7x584hrqU6aNIkpU6ZsVb58+XL+8Y9/kJWVRdu2benXrx9du3blzDPPzDsdtDRMmDCBwYMHM2DAAB577LEi62/YsIExY8YwYcIEpk2blvdZmTVrFv369eOuu+7isssu49lnnwWgUaNGvP322zz33HOlFrNUAO6esRcwHrgw+r8BsACoA3QGrixgmuHA66nM/+CDD/aCzJ07t8BxFcWECRO8Vq1aftxxx8WOHzNmjNeqVct79+5drPlv3rzZAX/ttdeKrDts2DA//PDD84YnT57sgM+bNy+v7KKLLvIGDRr4li1b8k3bs2fPYsVXnmbOnOmXXHJJgeM7dOjgXbt2LXB8s2bNfMSIEe7unp2d7QcccIDvs88+vnnz5hLH9swzz+T7TBx22GE+Y8aMAusvX77cjz32WJ8zZ06+8i1btnjTpk39u+++yxtu06aNL1q0KK9O3759/cMPPywypkx+306/7y0//b63Mra87REwy2P2qZm+DuJSYF8zuwa4CTjZ3X8COgGnZTiWCqdq1aqce+65TJ06lTlz5uQbt2XLFqZNm0bnzp2pUqVKseafznTJZ6qcfPLJ7LTTTvl+Rffp04cVK1Ywffr0vLKZM2dy+OGHFyu+8uLuDBgwgAsvvDB2/FtvvUXNmjWZMWPGVu9LrmrVquX9X6NGDfr06cMnn3zCxx9/XOL4hg8fzhlnnJE3fOKJJzJixIjYujk5OXTv3p0hQ4aw33775Ru3cuVKlixZwpo1awDIysqiSpUqrF27Nq/OFVdcwUUXXVTimKViyOiV1O6+DhgYUz4aGF3ANMPLKp7rnv+UuYvXlNXsC9W+WW2uPXHvtKc75ZRTmDZtGjfffHO+roQpU6bQo0cPHn300Xz1c3JyuO2221i3bh3ff/89a9as4d5776VJkyYAzJ8/nxtvvJE99tiD77//Pt+069evZ8yYMWRnZ/Piiy/Ss2dPrrzyyti4atasSc+ePZk8eTLDhg0DYPHixVSrVo1JkybRrVs3AJ588kmuvPJKfv75Z8aOHcuECRO44447GDx4MKeccgpXX301l112Gfvuuy+vvPIKBx10ECNHjuTtt99m9OjR1KlTh913352RI0fSqlUrHnnkEVq1asW4ceMYP34848eP58orr+SLL76gf//+3HLLLQCsWrWKsWPH8ssvvzB16lQuvfRS+vTpwyOPPMJ9993Hn/70J6ZMmcLatWuZPTv/xf1vvPEGK1euZM8994xd9/Hjx/Pkk0/SpUsX7rnnHiZMmFDk++jRyXwlvdr4hx9+4KOPPmL33XfPK2vXrh3Dhg1j8+bNVK2a/yv+4IMPsmTJEubMmcNdd91F06ZNuf3222nQoAENGzbk2GOPpW/fvkybNo2PPvqIU045Jd9677333nz11Ve8++67HHLIISWKXbZ9ullfBZOVlcVll13Gk08+yYIFC/LKH3vsMXr16rVV/ZEjR7J27Vquv/56HnzwQerUqcOpp54KhH7o7t27c/XVVzN8+HDOP//8fNMOHTqUk046iWuvvZaHH36Yq666ipdffrnA2Pr06cNnn33G+++/D8Dzzz/PVVddxVNPPcWGDRvIyclhxYoVNG7cmFq1anHYYYexYMECvvjiCx577DFOOukkbr31VqpVq8YVV1zB9ddfz80338yKFSvo2LEjP//8M6+LZQ0AABFtSURBVO+++y7dunVj/vz55OTk0Lt3b2rUqEHXrl354osv+N///serr77KzTffzK233sozzzwDwF/+8hcGDBjATTfdxI033sg555zDvHnz6N69O59++imvv/46DzzwAJdeeulW6/Wf//yHdu3axa7zwoULqVGjBk2aNGHgwIE8+uijrFq1qtD3cPXq1UycOJFjjz02344dYPTo0QwYMKDA1+LF+Q/DLVwYzvFo0KBBXlnt2rXZsGEDy5cv32rZDz30EJ07d+biiy/m6aef5oMPPqBHjx5545944gl+85vfcMghhzB16lRuuummreax55578uKLLxa6jrJ9qFQ360tWnF/w24K+ffty7bXXcvvtt3Pvvffyyiuv0LVrV3bYYYd89XJycrjrrrvytTQGDRpEhw4deO+99/j444+pXr06e+21FwCdO3fOq+fuPP7447Rs2ZL//ve/ABx33HH8+OOPBcbVrVs3dtllFx599FHatGnDDjvswHnnnceNN97I888/T/369fNaElWqVKF583C+Qs+ePWnVqhUALVu2xN1ZtWoVM2bMAGDt2rU0aNCARo0a0ahRIzp16gTA1Vdfzemnn863336b1yLq1asXO+20ExdccAFjxozh2Wef5dBDD+XNN99k0qRwUX52djZHH300CxcupF27dtSpU4cTTzyRPffcM7aVMH/+fBo2bBi7zmPHjmXQoHA3mH79+jFs2DAmTpzI5ZdfvlXdmTNncueddzJ//nz69u3L4MGDt6pz8cUXF7h94+R29SXeJSD3gHNy6wHgo48+4qyzzqJ69epUr16dyy+/nLPOOouvv/6aVq1asW7dOv7whz9Qr149Bg0aRLNmzbaKqUmTJnz22WdpxSkVU6VOEBVVjRo1GDx4MCNGjGD48OHcf//9eWcPJVq2bBkrVqzId9uDNm3aAPD9998ze/Zsdtppp9hlLFu2jFWrVjF48GCyskJD85JLLik0LjOjd+/ePPzww7Rv354ePXqw22670bVrVyZNmsSuu+7KDTfckK9+4l+Apk2bcsMNN9CwYUOOPDJcfJ/bHZNs3333BUL3UeIv6MTxq1at4ttvv6Vq1ar54v/rX/+aL47Crv5dv3597Pyzs7OZNm1avvhat27Nvffey5AhQ/K2W65OnToxZMiQApcDcOeddzJ37twCx19//fU0a9Ysb7hFi3Cd6apVq/KS7KpVq6hVqxb169ffavrNmzfnO9Z04IEHArBixQp22WUXTjzxRF566SUaNmxI48aN6dGjB7/97W/p2LFj3jTVq1ePbZ3I9kcJooIaOHAgI0eO5Pzzz6dt27axfdmNGjVixx135JNPPtnqmoX27dvz4Ycf8sUXX7Bp06Z8B1Hh1y6Lp556itNPPz2vfMaMGXTt2rXAuPr06cPIkSMZO3ZsXldTnz59GDRoEGeddVaRfe6DBg1i991359JLL+Wbb74ptO6GDRvIysqiTZs2rFy5Mnb8XnvtRbNmzViwYAEzZ87Ma32sX7+ejz/+ON+OryCNGjXKd6A216RJkxg2bBgnn3xyXlnPnj3p2LEjL7zwAt27dy9y3smKSiDJmjRpwoEHHsi8efM46KCDAPjyyy856qijtkpQAAcccADz58/PG65atSo77LADbdq0Yc6cOSxevDivtdS9e3d69erF9OnT822n7Ozs2IQp2x8dg6hAtmzZwubN4cLzunXrcv755zN16tR8XQCbN2/Oq5OVlcVFF13ExIkT2bBhAxCuWTjhhBNo27YtPXr0YOXKlXm/6nOPafz444+4O3369OG8885j9OjRTJ8+nUGDBuV15fivpyHn065dOw4++GCOPPLIvB3UaaedRlZWFscff3yB65Vr1qxZLFy4kC1btuQd71ixYkVe33tiH/yrr77Kueeemy/p5I7Pzs7m/fff58ILL6RFixYceeSRnHTSSTzwwAO89tprDBw4MF//f2IMyTp06LDVAfycnByefPLJrZJAhw4dOPjgg7njjjvylSe+L6Xt8ssv59///jcQ3pd///vfDB06FAgHsS+77LK8a06GDh3KlClTWL9+PRAS/gUX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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.metrics import plot_precision_recall_curve\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.metrics import average_precision_score\n",
    "\n",
    "\n",
    "average_precision = average_precision_score(to_one_hot(y_test), class_probs)\n",
    "fig = plot_precision_recall_curve(model_wrapper, Xt_test, y_test)\n",
    "fig.ax_.set_title(\n",
    "    '2-class Precision-Recall curve: '\n",
    "    'AP={0:0.2f}'.format(average_precision)\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "import tensorflow_probability as tfp\n",
    "tfd = tfp.distributions\n",
    "from tensorflow import keras\n",
    "\n",
    "negloglik = lambda y, p_y: -p_y.log_prob(y)\n",
    "\n",
    "model = keras.Sequential([\n",
    "  keras.layers.Dense(12, activation='relu', name='hidden'),\n",
    "  keras.layers.Dense(1, name='output'),\n",
    "  tfp.layers.DistributionLambda(\n",
    "      lambda t: tfd.Bernoulli(logits=t)\n",
    "  ),\n",
    "])\n",
    "\n",
    "model.compile(optimizer=tf.optimizers.Adagrad(learning_rate=0.05), loss=negloglik)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
